#### 可变长位置参数 --> *变量名可以定义任意数量的元素给这个可变长变量
def myargs(*num):
    print(*num)
    print(type(*num), num)
myargs(1)

def myargs1(*num):
    print(*num)
    # 可以指定输出某个位置的元素
    print(num[0])
    print(num[1])
myargs1(1, 2)
myargs1(1, 2, 3, 4)
print()
# 结果：
# 1
# <class 'int'> (1,)
# 1 2
# 1
# 2
# 1 2 3 4
# 1
# 2

a = (1, 2, 3)
# 有*后会输出该列表所有的元素，以空格作为分割符
print(*a)
# 1 2 3

# 这个输出的是一个列表
print(a)
# (1, 2, 3)
print()

#### 可变长关键字参数 --》 字典
def myargs2(**num):
    print(num)
    # 下行输出无法实现
    # print(**num)
myargs2(a=1, b=2, c=3)
myargs2(b=2, a=3)
print()

b = {'b1': 1, 'b2': 2}
print("b1 is {b1}, b2 is {b2}".format(**b))
print()

def max_num(x, y):
    print("return语句...")
    if x > y:
        print("return x")
        return x
    else:
        print("return y")
        return y
    print("return end...")


result = max_num(1, 2)
print(result)
print()

# -----------------------------------------------------------------
#### 匿名函数
# 不需要传递函数名
add = lambda x, y: x + y
print(add(1, 2))

add = lambda x, y: x if x > y else y
print(add(1, 2))
print()

# -----------------------------------------------------------------
#### 递归函数
# 自己调用自己
# 1*2*3*4
num = 1
n = 4
for i in range(1, n+1):
    num *= i
print(num)
print()

# 用递归函数
def func(n):
    if n == 1:
        return 1
    else:
        return n * func(n-1)
print(func(4))
# 能不用递归就尽量不用递归 --》 非常占内存且效率低下
print()

# -----------------------------------------------------------------
#### 换所的参数传递
# 本质传递引用
## 传递不可变数据类型 --> 普通的变量是不可变数据类型
def func1(x):
    print(id(x))
    # 重新创建了一个局部变量x = 100
    x = 100
    print(x)
# 首先创建了一个全局变量x = 1
x = 1
print(id(x))
# 函数内部改变了x的值,但是因为函数内部的x为局部变量,全局上的x值不会改变
func1(x)
print(x)
print()

## 传递可变数据类型 --> 首先知道list是个可变数据类型,再函数内部修改,在外也可生效
def f(x):
    x[0] = 100
    print(x)
a = [1, 2, 3]
f(a)
print(a)
print()

## 参数定义时,尽量不要定义为一个可变数据类型
# 因为list是个可变数据类型
def f(a=[]):
    a.append(1)
    print(a)
f()
f()
f()
print()
# 结果:
# [1]
# [1, 1]
# [1, 1, 1]

#####变量名的解析原则#####
# LEGB
# 从本地变量中 --> 函数内部
# 在任意上层函数的作用域
# 在全局作用域
# 在内置作用域 --> 例如 __name__ 就是一个,如果自定义了会覆盖内置变量
def other():
    __name__ = 5
    def inner():
        # __name__ = 4
        print(__name__)
    inner()
__name__ = 6
other()